#include "rrCintamaniDOM.h"
#include "JSObject.h"
#include "JSCallback.h"
#include "variant_list.h"
#include "DOM/Document.h"
#include "global/config.h"
#include "DOM/Window.h"

rrCintamaniElementStyle::rrCintamaniElementStyle( const FB::DOM::ElementPtr & style ) : mStyle(style)
{

}

rrCintamaniElementStyle::~rrCintamaniElementStyle()
{

}

void rrCintamaniElementStyle::SetBackground( const std::string & Colour ) {
	mStyle->setProperty("background",Colour);
}

void rrCintamaniElementStyle::SetWidth( const std::string & Width ) {
	mStyle->setProperty("width",Width);
}

void rrCintamaniElementStyle::SetHeight( const std::string & Height ) {
	mStyle->setProperty("height",Height);
}

void rrCintamaniElementStyle::SetMarginTop( const std::string & top ) {
	mStyle->setProperty("marginTop",top);
}

void rrCintamaniElementStyle::SetPaddingTop( const std::string & top ) {
	mStyle->setProperty("paddingTop",top);
}
 
void rrCintamaniElementStyle::SetProperty( const std::string & prop, const std::string & val ) {
	mStyle->setProperty(prop,val);
}

void rrCintamaniElementStyle::SetDisplay( const std::string & Display ) {
	mStyle->setProperty("display",Display);
}

void rrCintamaniElementStyle::SetFontSize( const std::string & FontSize ){
	mStyle->setProperty("fontSize", FontSize );
}

//===================================================

rrCintamaniElement::rrCintamaniElement( const FB::DOM::ElementPtr & Ele) : mElement(Ele)
{

}

rrCintamaniElement::~rrCintamaniElement()
{

}

void rrCintamaniElement::AddListener( rrCintamaniElementCallback * Listener )
{
	mListeners.push_back(Listener);
}

FB::DOM::DocumentPtr rrCintamaniElement::GetOwnerDocument() const
{
	FB::JSObjectPtr api = mElement->getProperty<FB::JSObjectPtr>("ownerDocument");
	return FB::DOM::Document::create(api);
}

FB::JSObjectPtr rrCintamaniElement::GetJSObject() const { 
	return mElement->getJSObject();
}

void rrCintamaniElement::AppendChild( rrCintamaniElementPtr child ){
	mElement->appendChild( child->mElement );
}

void rrCintamaniElement::GetElementsByTagName(const std::string &name, std::vector<rrCintamaniElementPtr> & tagList ) const {
	std::vector<FB::DOM::ElementPtr> Elements = mElement->getElementsByTagName(name);
	for(int i = 0 ; i < Elements.size(); i++ ) {
		tagList.push_back( rrCintamaniElementPtr( new rrCintamaniElement( Elements[i] ) )  );
	}
}

void rrCintamaniElement::SetInnerHtml( const std::string & html ) {
	mElement->setInnerHTML( html );
}

std::string rrCintamaniElement::GetInnerHtml( ) const {
	return mElement->getInnerHTML();
}

std::string rrCintamaniElement::GetTextContent( ) const {
	return mElement->getProperty<std::string>("textContent");
}

void rrCintamaniElement::SetTextContent(const std::string & textContent) {
	mElement->setProperty("textContent", textContent);
}	

std::string rrCintamaniElement::GetTagName() const {
	return mElement->getProperty<std::string>("tagName");
}

std::string rrCintamaniElement::GetId() const {
	return mElement->getProperty<std::string>("id");
}

void rrCintamaniElement::SetId(const std::string & Id) {
	mElement->setProperty("id",Id);
}

std::string rrCintamaniElement::GetClassName() const {
	return mElement->getProperty<std::string>("className");
}

void rrCintamaniElement::SetClassName(const std::string & className) {
	mElement->setProperty("className",className);
}

void rrCintamaniElement::SetName(const std::string & name) {
	mElement->setProperty("name", name);
}

void rrCintamaniElement::SetNodeName(const std::string & nodeName) {
	mElement->setProperty("nodeName", nodeName);
}

bool rrCintamaniElement::HasAttribute( const std::string & attributename ) {
	return mElement->callMethod<bool>("hasAttribute", FB::variant_list_of(attributename)); 
}

std::string rrCintamaniElement::GetAttribute( const std::string & attributename ) const {
	return mElement->callMethod<std::string>("getAttribute", FB::variant_list_of(attributename)); 
}

void rrCintamaniElement::SetAttribute( const std::string & name, const std::string & value) {
	mElement->callMethod<FB::JSObjectPtr>("setAttribute", FB::variant_list_of(name)(value)); 
}

rrCintamaniElementStylePtr rrCintamaniElement::GetStyle() const {
	FB::JSObjectPtr style = mElement->getProperty<FB::JSObjectPtr>("style");
	return rrCintamaniElementStylePtr(  new rrCintamaniElementStyle( FB::DOM::Element::create(style) ));
}

void rrCintamaniElement::AddEventListener( const std::string name, const FB::JSAPIPtr & pt )
{
	mElement->callMethod<FB::JSObjectPtr>("addEventListener", FB::variant_list_of(name)(pt)); 
}

void rrCintamaniElement::OnClick() {
	for( int i = 0 ; i < mListeners.size(); i++ ) {
		mListeners[i]->OnClick(this);
	}
}

void rrCintamaniElement::OnTouchStart()
{

}

/// rrCintamaniElementVideo //

rrCintamaniElementVideo::rrCintamaniElementVideo( const FB::DOM::ElementPtr & Ele  ) : rrCintamaniElement( Ele )
{
	static int VideoId = 0;
	std::ostringstream oStr;
	oStr << VideoId;
	mClassName= "player" + oStr.str();
	VideoId++;	
}

rrCintamaniElementVideo::~rrCintamaniElementVideo()
{

}

void rrCintamaniElementVideo::AddEventListener( const std::string name, const FB::JSAPIPtr & pt )
{
	mElement->callMethod<FB::JSObjectPtr>("addEventListener", FB::variant_list_of(name)(pt)); 
}

void rrCintamaniElementVideo::OnClick()
{
	mElement->getJSObject()->getHost()->getDOMWindow()->alert("Video Clicked! Disable other playbacks...");
}

void rrCintamaniElementVideo::OnResize()
{
	mElement->getJSObject()->getHost()->getDOMWindow()->alert("mouse down");
}

void rrCintamaniElementVideo::Initialize( const std::string & url )
{
	//http://www.html5rocks.com/en/mobile/touch/
	//https://developer.mozilla.org/en-US/docs/Mozilla_event_reference?redirectlocale=en-US&redirectslug=DOM%2FDOM_event_reference

	// Test avec le tag Object
	FB::DOM::ElementPtr object = GetOwnerDocument()->createElement("object");
	object->callMethod<FB::JSObjectPtr>("setAttribute", FB::variant_list_of("width")("640")); 
	object->callMethod<FB::JSObjectPtr>("setAttribute", FB::variant_list_of("height")("480")); 

	FB::DOM::ElementPtr param1 = GetOwnerDocument()->createElement("param");
	param1->callMethod<FB::JSObjectPtr>("setAttribute", FB::variant_list_of("name")("movie")); 
	param1->callMethod<FB::JSObjectPtr>("setAttribute", FB::variant_list_of("value")("https://www.youtube.com/v/Zhawgd0REhA?controls=0&enablejsapi=1&modestbranding=1&rel=0&showinfo=0&version=3")); 
	object->appendChild( param1 );
	FB::DOM::ElementPtr embed = GetOwnerDocument()->createElement("embed");
	embed->callMethod<FB::JSObjectPtr>("setAttribute", FB::variant_list_of("src")("https://www.youtube.com/v/Zhawgd0REhA?controls=0&enablejsapi=1&modestbranding=1&rel=0&showinfo=0&version=3")); 
	embed->callMethod<FB::JSObjectPtr>("setAttribute", FB::variant_list_of("type")("application/x-shockwave-flash")); 
	embed->callMethod<FB::JSObjectPtr>("setAttribute", FB::variant_list_of("allowfullscreen")("true")); 
	embed->callMethod<FB::JSObjectPtr>("setAttribute", FB::variant_list_of("width")("100%")); 
	embed->callMethod<FB::JSObjectPtr>("setAttribute", FB::variant_list_of("height")("100%")); 
	
	object->appendChild( embed );
	mElement->appendChild( object );


	// Test avec le Tag Iframe
	//SetAttribute("type","text/html");
	//SetAttribute("width","100%");
	//SetAttribute("frameborder","0");
	//SetAttribute("src","https://www.youtube.com/embed/Zhawgd0REhA?modestbranding=1&controls=0&enablejsapi=1&rel=0&showinfo=0&iv_load_policy=3");
	//SetClassName( mClassName );
	//SetId( mClassName );
	//GetStyle()->SetMarginTop( "20px") ;
 
}

void rrCintamaniElementVideo::Stop()
{
	mElement->getJSObject()->getHost()->evaluateJavaScript("JavascriptCall");
}